package com.rbac.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rbac.modules.system.dto.RoleDTO;
import com.rbac.modules.system.dto.RoleQuery;
import com.rbac.modules.system.entity.Role;
import com.rbac.modules.system.entity.SysUserRole;
import com.rbac.modules.system.mapper.RoleMapper;
import com.rbac.modules.system.service.RoleService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import jakarta.annotation.Resource;
import java.util.List;

@Service
public class RoleServiceImpl implements RoleService {

    @Resource
    private RoleMapper roleMapper;

    @Override
    public Page<Role> page(RoleQuery query) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(query.getRoleName()), Role::getRoleName, query.getRoleName())
                .like(StringUtils.hasText(query.getRoleCode()), Role::getRoleCode, query.getRoleCode())
                .eq(query.getStatus() != null, Role::getStatus, query.getStatus())
                .orderByDesc(Role::getCreateTime);

        return roleMapper.selectPage(new Page<>(query.getCurrent(), query.getSize()), wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(RoleDTO roleDTO) {
        // 检查角色编码是否存在
        if (checkRoleCodeExists(roleDTO.getRoleCode(), null)) {
            throw new RuntimeException("角色编码已存在");
        }

        Role role = new Role();
        BeanUtils.copyProperties(roleDTO, role);
        roleMapper.insert(role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(RoleDTO roleDTO) {
        // 检查角色编码是否存在
        if (checkRoleCodeExists(roleDTO.getRoleCode(), roleDTO.getId())) {
            throw new RuntimeException("角色编码已存在");
        }

        Role role = new Role();
        BeanUtils.copyProperties(roleDTO, role);
        roleMapper.updateById(role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        roleMapper.deleteById(id);
    }

    @Override
    public Role getById(Long id) {
        return roleMapper.selectById(id);
    }

    @Override
    public boolean checkRoleCodeExists(String roleCode, Long excludeId) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getRoleCode, roleCode)
                .ne(excludeId != null, Role::getId, excludeId);
        return roleMapper.selectCount(wrapper) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignUsers(Long roleId, List<Long> userIds) {
        // 先删除该角色的所有用户关联
        roleMapper.deleteUserRoleByRoleId(roleId);

        // 批量添加新的用户关联
        for (Long userId : userIds) {
            roleMapper.insertUserRole(userId, roleId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignPermissions(Long roleId, List<Long> permissionIds) {
        // 先删除该角色的所有权限关联
        roleMapper.deleteRolePermissionByRoleId(roleId);

        // 批量添加新的权限关联
        for (Long permissionId : permissionIds) {
            roleMapper.insertRolePermission(roleId, permissionId);
        }
    }

    @Override
    public List<Long> getRolePermissions(Long roleId) {
        return roleMapper.getRolePermissions(roleId);
    }

    @Override
    public List<Long> getRoleUsers(Long roleId) {
        return roleMapper.getRoleUsers(roleId);
    }
}
